----------------------------------------------------------------------------------
-- Company:
-- Engineer: Kurt Metzger
--
-- Create Date: 18:42:25 02/26/2009
-- Design Name:
-- Module Name: UART_transmitter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.

--library UNISIM;
--use UNISIM.VComponents.all;

entity UART_transmitter is
	Generic (baud_rate: integer := 115200);
	Port ( 	tx : out STD_LOGIC;
				cts_in_n : in STD_LOGIC :='0';
				transmit_byte : in STD_LOGIC_VECTOR (7 downto 0);
				req_out : out STD_LOGIC;
				ack_in : in STD_LOGIC;
				clk : in STD_LOGIC;
				reset : in STD_LOGIC :='0');
end UART_transmitter;

architecture Behavioral of UART_transmitter is


-- baud count is (50000000/baud_rate - 1)


	signal baud_count : std_logic_vector(19 downto 0) :=
		STD_LOGIC_VECTOR(CONV_UNSIGNED((50000000/baud_rate)-1, 20));
	signal baud_counter : std_logic_vector(19 downto 0);
	signal bit_counter : std_logic_vector(3 downto 0);
	signal sr_out : std_logic_vector(9 downto 0) := (others=>'1');
			signal read_fifo : std_logic;
			signal data_present : std_logic;
			signal fifo_data_out : std_logic_vector(7 downto 0);
			signal half_full : std_logic;
	signal cts_delay : std_logic_vector(1 downto 0) := (others=>'0');
	type t_state is (s_idle, s_active);
	signal state : t_state := s_idle;


begin

	tx <= sr_out(0);
	req_out <= not half_full;


	process(clk, ack_in, reset)
	begin
		if reset = '1' then
			state <= s_idle;
		elsif rising_edge(clk) then

		baud_counter <= baud_counter-1;
		read_fifo <= '0';
		cts_delay <= cts_delay(0) & cts_in_n;

		case state is
			when s_idle =>
				if data_present = '1' and cts_delay = "00" then
					sr_out <= '1' & fifo_data_out & '0';
					baud_counter <= baud_count;
					bit_counter <= "1010";
					read_fifo <= '1';
					state <= s_active;
				end if;

			when s_active =>
				if baud_counter = 0 then
					bit_counter <= bit_counter-1;
					baud_counter <= baud_count;
					sr_out <= '1' & sr_out(9 downto 1);
					if bit_counter = 0 then
						state <= s_idle;
					end if;
				end if;
		end case;
	end if;
end process;

	txfifo : entity work.FIFO_16xN
	port map(
		data_in => transmit_byte, -- data to transmit
		write => ack_in, -- write into fifo
		half_full => half_full, -- invert for request data
		data_out => fifo_data_out, -- data from fifo
		data_present => data_present, -- values are in fifo
		read => read_fifo, -- read value from the fifo
		reset => reset,
		clk => clk);

end Behavioral;